<template>
  <div class="bpmn-com containers">
    <!-- 画布区域 -->
    <div class="canvas" ref="canvas"></div>

    <!-- 侧边栏区域 -->
    <div class="panel" ref="properties"></div>
  </div>
</template>

<script>
import {
  BpmnPropertiesPanelModule, // 基础侧边栏渲染入口
  BpmnPropertiesProviderModule, // 侧边栏属性编辑表单构造器
} from "bpmn-js-properties-panel";
import BpmnModeler from "bpmn-js/lib/Modeler";
import { xmlStr } from "@/mock/index.js";
import camundaModdleDescriptor from "camunda-bpmn-moddle/resources/camunda";

import { getElementListByRegisstry } from "@/utils/index.js";
export default {
  name: "BaseBpmn",
  data() {
    return {
      bpmnModeler: null,
      canvas: null,
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      this.initBpmnModeler();
    },
    initBpmnModeler() {
      this.canvas = this.$refs.canvas;
      this.bpmnModeler = new BpmnModeler({
        container: this.canvas,
        keyboard: { bindTo: document },
        propertiesPanel: {
          parent: this.$refs["properties"], // 侧边栏挂载的 Dom Id
        },
        // 添加到扩展模块内
        additionalModules: [
          BpmnPropertiesPanelModule,
          BpmnPropertiesProviderModule,
        ],
        moddleExtensions: {
          camunda: camundaModdleDescriptor,
        },
      });
      this.createNewDiagram(xmlStr);
    },
    /**
     * 创建新的画布
     */
    async createNewDiagram(xml) {
      // 将字符串转换成图显示出来
      let newId = this.processId || `Process_${new Date().getTime()}`;
      let newName = this.processName || `业务流程_${new Date().getTime()}`;
      let xmlString = xml;
      // let xmlString = xml || DefaultEmptyXML(newId, newName, this.prefix);
      try {
        let { warnings } = await this.bpmnModeler.importXML(xmlString);
        if (warnings && warnings.length) {
          warnings.forEach((warn) => console.warn(warn));
        }
        this.success();
      } catch (e) {
        console.error(`[Process Designer Warn]: ${e?.message || e}`);
      }
    },
    /**
     * 画布成功创建后
     */
    success() {
      console.log("ok");
      this.addModelerListener();
      this.addEventBusListener();
    },
    /**
     *
     */
    addModelerListener() {
      const bpmnjs = this.bpmnModeler;
      const _vm = this;

      const lineEvent = ["shape.added", "shape.move.end", "shape.removed"];
      const lineConnectEvent = ["connect.end", "connect.move"];

      const events = lineConnectEvent.concat(lineEvent);
      events.forEach((event) => {
        _vm.bpmnModeler.on(event, (e) => {
          console.log(event, e);
          var elementRegistry = bpmnjs.get("elementRegistry");
          var shape = e.element ? elementRegistry.get(e.element.id) : e.shape;
          console.log(shape);
        });
      });
    },
    /**
     * 元素点击、元素选择事件监听
     */
    addEventBusListener() {
      let _vm = this;
      const bpmnjs = this.bpmnModeler;

      const eventBus = this.bpmnModeler.get("eventBus");
      const eventTypes = ["element.click", "element.changed"];
      eventTypes.forEach((eventType) => {
        eventBus.on(eventType, (e) => {
          // 根节点触发
          if (!e || e.element.type === "bpmn:Process") {
            return;
          }
          if (eventType === "element.changed") {
            _vm.elementChanged(eventType, e);
          } else {
            const elementRegistry = bpmnjs.get("elementRegistry");
            var shape = e.element ? elementRegistry.get(e.element.id) : e.shape;

            console.log("元素组册", getElementListByRegisstry(elementRegistry));
            console.log("点击了element", shape);
          }
        });
      });
    },
    // 元素改变事件
    elementChanged(eventType, e) {
      let shape = this.getShape(e.element.id);
      console.log(123, e, shape);
      if (!shape) {
        console.log("无效的shape");
        // 由于上面已经用 shape.removed 检测了shape的删除, 因此这里只判断是否是线
        if (this.isSequenceFlow(shape.type)) {
          console.log("删除了线");
        }
      }
      if (!this.isInvalid(shape.type)) {
        if (this.isSequenceFlow(shape.type)) {
          console.log("改变了线");
        }
      }
    },
    getShape(id) {
      var elementRegistry = this.bpmnModeler.get("elementRegistry");
      return elementRegistry.get(id);
    },
    isInvalid(param) {
      // 判断是否是无效的值
      return param === null || param === undefined || param === "";
    },
    isSequenceFlow(type) {
      // 判断是否是线
      return type === "bpmn:SequenceFlow";
    },
  },
};
</script>

<style lang="scss" scoped>
.containers {
  position: absolute;
  background-color: #ffffff;
  width: 100%;
  height: 100%;
  .canvas {
    width: 100%;
    height: 100%;
  }
  .panel {
    position: fixed;
    right: 0;
    top: 0;
    width: 300px;
  }
}
</style>
